home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume2
/
unix
/
shel301a.2
< prev
next >
Wrap
Text File
|
1988-12-06
|
55KB
|
2,203 lines
Path: xanth!ames!ncar!mailrus!ulowell!page
From: page@swan.ulowell.edu (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v02i088: shell - csh-like shell v3.01a, Part02/03
Message-ID: <10489@swan.ulowell.edu>
Date: 5 Dec 88 22:32:58 GMT
Organization: University of Lowell, Computer Science Dept.
Lines: 2192
Approved: page@swan.ulowell.edu
Submitted-by: PERUGIA@ICNUCEVM.BITNET (Cesare Dieni)
Posting-number: Volume 2, Issue 88
Archive-name: unix/shell301a.2
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# globals.c
# main.c
# makefile
# rawconsole.c
# run.c
# set.c
# shell.h
# shellfunctions.h
# sub.c
# This archive created: Mon Dec 5 17:25:21 1988
cat << \SHAR_EOF > globals.c
/*
* GLOBALS.C
*
* (c)1986 Matthew Dillon 9 October 1986
*
* Version 2.07M by Steve Drew 10-Sep-87
*
* Most global variables.
*
* Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
*
*/
char *v_titlebar="_titlebar"; /* Window title */
char *v_prompt ="_prompt"; /* your prompt (ascii command) */
char *v_hist ="_history"; /* set history depth (value) */
char *v_histnum ="_histnum"; /* set history numbering var */
char *v_debug ="_debug"; /* set debug mode */
char *v_verbose ="_verbose"; /* set verbose for source files */
char *v_stat ="_maxerr"; /* worst return value to date */
char *v_lasterr ="_lasterr"; /* return value from last comm. */
char *v_cwd ="_cwd"; /* current directory */
char *v_except ="_except"; /* "nnn;command" */
char *v_passed ="_passed"; /* passed arguments to source file */
char *v_path ="_path"; /* search path for external commands */
char *v_gotofwd ="_gtf"; /* set name for fwd goto name */
struct HIST *H_head, *H_tail; /* HISTORY lists */
struct PERROR Perror[]= { /* error code->string */
103, "Insufficient free storage",
105, "Task table full",
120, "Argument line invalid or too long",
121, "File is not an object module",
122, "Invalid resident library during load",
201, "No default directory",
202, "Object in use",
203, "Object already exists",
204, "Directory not found",
205, "Object not found",
206, "Bad stream name",
207, "Object too large",
209, "Action not known",
210, "Invalid stream component name",
211, "Invalid object lock",
212, "Object not of required type",
213, "Disk not validated",
214, "Disk write protected",
215, "Rename across devices",
216, "Directory not empty",
217, "Too many levels",
218, "Device not mounted",
219, "Seek error",
220, "Comment too long",
221, "Disk full",
222, "File delete protected",
223, "File write protected",
224, "File read protected",
225, "Not a DOS disk",
226, "No disk",
/* custom error messages */
500, "Bad arguments",
501, "Label not found",
502, "Must be within source file",
503, "Syntax Error",
504, "Redirection error",
505, "Pipe error",
506, "Too many arguments",
507, "Destination not a directory",
508, "Cannot mv a filesystem",
509, "Error in command name",
510, "Bad drive name",
511, "Illegal number",
0, NULL
};
char *av[MAXAV]; /* Internal argument list */
long Src_base[MAXSRC]; /* file pointers for source files */
long Src_pos[MAXSRC]; /* seek position storage for same */
char If_base[MAXIF]; /* If/Else stack for conditionals */
int H_len, H_tail_base; /* History associated stuff */
int H_stack; /* AddHistory disable stack */
int E_stack; /* Exception disable stack */
int Src_stack, If_stack; /* Stack Indexes */
int forward_goto; /* Flag for searching for foward lables */
int ac; /* Internal argc */
int debug; /* Debug mode */
int disable; /* Disable com. execution (conditionals)*/
int Verbose; /* Verbose mode for source files */
int Lastresult; /* Last return code */
int Exec_abortline; /* flag to abort rest of line */
int Quit; /* Quit flag */
long Cout, Cin; /* Current input and output file handles*/
long Cout_append; /* append flag for Cout */
char *Cin_name, *Cout_name; /* redirection input/output name or NULL*/
char *Pipe1, *Pipe2; /* the two pipe temp. files */
struct Process *Myprocess;
struct CommandLineInterface *Mycli;
int S_histlen = 20; /* Max # history entries */
unsigned int options;
SHAR_EOF
cat << \SHAR_EOF > main.c
/*
* MAIN.C
*
* Matthew Dillon, 24 Feb 1986
* (c)1986 Matthew Dillon 9 October 1986
*
* Version 2.07M by Steve Drew 10-Sep-87
*
* Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
*
*/
char *shellctr="CshCounter";
extern char *v_titlebar, *v_prompt, *v_hist, *v_lasterr, *v_path;
int aux; /* for use with aux: driver */
char *oldtitle;
char trueprompt[100];
char Inline[260];
struct IntuitionBase *IntuitionBase;
struct Window *w;
struct ArpBase *ArpBase;
main(argc, argv)
register char *argv[];
{
#if RAW_CONSOLE
char *rawgets();
#endif
register unsigned int i;
extern int Enable_Abort;
char buf[10];
ArpBase=(struct ArpBase *)OpenLibrary("arp.library",34L);
if (ArpBase==NULL) { printf("No arp library\n"); exit(0); }
Forbid();
i=Errno=0;
if (Getenv(shellctr,buf,10L)) {
i=(int)(long)Atol(buf);
if (Errno) i=0;
}
sprintf(buf,"%d",i+1);
Setenv(shellctr,buf);
Permit();
IntuitionBase=(struct IntuitionBase *)ArpBase->IntuiBase;
w=IntuitionBase->ActiveWindow;
oldtitle=(char *)(w->Title);
set_var(LEVEL_SET, v_titlebar, "CShell V3.01A");
set_var(LEVEL_SET, v_prompt,
(IsInteractive(Input())) ? "\23337m%p> \2330m" : "");
set_var(LEVEL_SET, v_hist, "20");
set_var(LEVEL_SET, v_lasterr, "0");
set_var(LEVEL_SET, v_path, "RAM:,RAM:c/,df0:c/,df1:c/,sys:system/");
set_var(LEVEL_SET, "_insert", "1");
set_var(LEVEL_SET, "f1", "cdir df0:\15");
set_var(LEVEL_SET, "F1", "cdir df1:\15");
set_var(LEVEL_SET, "f3", "cdir RAM:\15");
set_var(LEVEL_SET, "F3", "cdir vd0:\15");
set_var(LEVEL_SET, "f4", "cd df0:\15");
set_var(LEVEL_SET, "F4", "cd df1:\15");
set_var(LEVEL_SET, "f5", "cls; ls\15");
set_var(LEVEL_SET, "F5", "cdir ");
set_var(LEVEL_SET, "f6", "lc\15");
set_var(LEVEL_SET, "f7", "info\15");
set_var(LEVEL_SET, "F7", "assign \15");
set_var(LEVEL_SET, "f8", "window -lf\15");
set_var(LEVEL_SET, "F8", "window -sb\15");
set_var(LEVEL_SET, "f10", "cls\15");
set_var(LEVEL_SET, "F10", "exit\15");
set_var(LEVEL_ALIAS, "cls", "echo -n ^l");
set_var(LEVEL_ALIAS, "lc", "ls -s");
set_var(LEVEL_ALIAS, "kr", "rm -r RAM:* >NIL:");
set_var(LEVEL_ALIAS, "cdir", "%q cd $q; cls; dir");
set_var(LEVEL_ALIAS, "exit", "endcli;quit");
set_var(LEVEL_ALIAS, "lp", "cat >PRT:");
init();
seterr();
do_pwd(NULL); /* set $_cwd */
Enable_Abort = 0;
for (i = 1; i < argc; ++i) {
if (!strcmp(argv[i],"-c")) {
Inline[0] = ' ';
Inline[1] = '\0';
while (++i < argc)
{ strcat(Inline,argv[i]); strcat(Inline," "); }
exec_command(Inline);
main_exit(Lastresult);
}
if (!strcmp(argv[i],"-a")) { aux = 1; continue; }
sprintf (Inline, "source %s",argv[i]);
av[1] = argv[i];
do_source (Inline);
}
for (;;) {
if (breakcheck())
while (WaitForChar(Input(), 100L) || stdin->_bp < stdin->_bend)
gets(Inline);
clearerr(stdin); /* prevent acidental quit */
#if RAW_CONSOLE
if (Quit || !rawgets(Inline, disable ? "_ " : trueprompt)) main_exit(0);
#else
printf("%s", disable ? "_ " : trueprompt);
fflush(stdout);
if (Quit || !gets(Inline)) main_exit(0);
#endif
breakreset();
if (*Inline) exec_command(Inline);
}
}
main_exit(n)
{
register unsigned short i;
char buf[10];
Getenv(shellctr,buf,10L);
i=(int)Atol(buf);
sprintf(buf,"%d",i-1);
Setenv(shellctr,buf);
SetWindowTitles(w,oldtitle,-1L);
for (i=1; i<MAXMYFILES; i++) myclose(i);
ArpExit(0L,0L); /* Intuition need not to be closed */
}
init()
{
static char pipe1[32], pipe2[32];
stdin->_flags |= 0x80; /* make sure we're set as a tty */
stdout->_flags |= 0x80; /* in case of redirection in .login */
#if RAW_CONSOLE
printf("\23312{"); /* enable window resize reports */
#endif
Close(_devtab[2].fd);
_devtab[2].mode |= O_STDIO;
_devtab[2].fd = _devtab[1].fd; /* set stderr to Output() otherwise */
/* don't work with aux driver */
Myprocess = (struct Process *)FindTask(0L);
Mycli=(struct CommandLineInterface *)((long)Myprocess->pr_CLI << 2);
Pipe1 = pipe1;
Pipe2 = pipe2;
sprintf(pipe1, "ram:pipe1_%ld", Myprocess);
sprintf(pipe2, "ram:pipe2_%ld", Myprocess);
}
breakcheck()
{
return (int)(SetSignal(0L,0L) & SIGBREAKF_CTRL_C);
}
breakreset()
{
SetSignal(0L, SIGBREAKF_CTRL_C);
}
dobreak()
{
if (breakcheck()) { printf("^C\n"); return(1); }
return(0);
}
/* this routine causes manx to use this Chk_Abort() rather than it's own */
/* otherwise it resets our ^C when doing any I/O (even when Enable_Abort */
/* is zero). Since we want to check for our own ^C's */
Chk_Abort()
{
return(0);
}
_wb_parse()
{
}
do_howmany()
{
char buf[10];
Getenv(shellctr, buf, 10L);
printf("Shell(s) running: %s\n",buf);
}
SHAR_EOF
cat << \SHAR_EOF > makefile
######################################################################
#
# Makefile to build Shell 3.01A
# by Carlo Borreo & Cesare Dieni 17-Nov-88
#
######################################################################
OBJS = run.o main.o comm1.o comm2.o comm3.o execom.o set.o sub.o \
globals.o rawconsole.o
INCL = shell.h
Shell : Shell.syms $(OBJS)
ln +q -m -o Shell $(OBJS) -la -lc
Shell.syms : $(INCL)
cc +HShell.syms shell.h
rawconsole.o : rawconsole.c $(INCL)
cc +IShell.syms rawconsole.c
run.o : run.c $(INCL)
cc +IShell.syms run.c
main.o : main.c $(INCL)
cc +IShell.syms main.c
comm1.o : comm1.c $(INCL)
cc +IShell.syms comm1.c
comm2.o : comm2.c $(INCL)
cc +IShell.syms comm2.c
comm3.o : comm3.c $(INCL)
cc +IShell.syms comm3.c
set.o : set.c $(INCL)
cc +IShell.syms set.c
sub.o : sub.c $(INCL)
cc +IShell.syms sub.c
globals.o : globals.c $(INCL)
cc +IShell.syms globals.c
execom.o : execom.c $(INCL)
cc +IShell.syms execom.c
SHAR_EOF
cat << \SHAR_EOF > rawconsole.c
/*
* RawConsole.c
*
* Shell 2.07M 17-Jun-87
* console handling, command line editing support for Shell
* using new console packets from 1.2.
* Written by Steve Drew. (c) 14-Oct-86.
* 16-Dec-86 Slight mods to rawgets() for Disktrashing.
*
* Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
*
*/
#if RAW_CONSOLE
extern int aux; /* for use with aux: */
#define SETRAW setrawcon(-1L);
#define SETCON setrawcon(0L);
char *rawgets(line,prompt)
char *line, *prompt;
{
char *get_var();
char *gets();
register int n, pl;
register int max, i;
unsigned char c1,c2,c3;
char fkeys[5];
char *s, *tyahdptr;
char *ps;
int fkey, savn;
int insert = 1;
char rep[20];
char typeahd[256];
static int width;
int recall = -1;
struct HIST *hist;
if (aux) {
printf("%s",prompt);
fflush(stdout);
}
if (!IsInteractive(Input()) || aux ) return(gets(line));
if (WaitForChar((long)Input(), 100L) || /* don't switch to 1L ...*/
stdin->_bp < stdin->_bend) { /* else causes read err's*/
gets(line);
return(line);
}
SETRAW;
printf("\015%s\2336n",prompt);
savn = pl = n = 0;
tyahdptr = typeahd;
while((typeahd[n]=getchar()) != 'R') {
if ((unsigned char)typeahd[n] == 155) savn = n;
n++;
}
/* typeahd now contains possible type a head chars
followed by <CSI> cursor position report.
*/
typeahd[savn] = '\0';
if (typeahd[n-2] != ';') pl = (typeahd[n-2] - 48) * 10;
pl += typeahd[n-1] - 49;
ps = line + pl;
line[max = i = pl] = '\0';
if (!width) width = 77;
if (s = get_var (LEVEL_SET, "_insert")) insert = atoi(s) ? 1 : 0;
while( (c1 = *tyahdptr) != '\0' || (c1 = getchar()) != 255) {
if (*tyahdptr) ++tyahdptr;
switch(c1) {
case 155:
c2 = getchar();
switch(c2) {
case 'A': /* up arrow */
n = ++recall;
case 'B': /* down arrow */
line[pl] = '\0';
if (recall >= 0 || c2 == 'A') {
if (c2 == 'B') n = --recall;
if (recall >= 0) {
for(hist = H_head; hist && n--;
hist = hist->next);
if (hist) strcpy(&line[pl],hist->line);
else recall = H_len;
}
}
if (i != pl)
printf("\233%dD",i);
printf("\015\233J%s%s",prompt,ps);
i = max = strlen(ps) + pl;
break;
case 'C': /* right arrow*/
if (i < max) {
i++;
printf("\233C");
}
break;
case 'D': /* left arrow */
if (i > pl) {
i--;
printf("\233D");
}
break;
case 'T': /* shift-up */
n = recall = H_len-1;
case 'S': /* shift-down */
line[pl] = '\0';
if (c2 == 'S') {
n = recall = 0;
if (H_head) strcpy(&line[pl], H_head->line);
}
else if (H_tail) strcpy(&line[pl], H_tail->line);
printf("\015\233J%s%s",prompt,ps);
i = max = strlen(ps) + pl;
break;
case ' ': /* shift -> <-*/
c3 = getchar();
switch(c3) {
case('@'): /* shift -> */
while (ps[i-strlen(prompt)] == ' ' && i<max) {
i++;
printf("\233C");
}
while (ps[i-strlen(prompt)] != ' ' && i<max) {
i++;
printf("\233C");
}
break;
case('A'): /* shift <- */
while (ps[i-strlen(prompt)-1] == ' ' && i>pl) {
i--;
printf("\233D");
}
while (ps[i-strlen(prompt)-1] != ' ' && i>pl) {
i--;
printf("\233D");
}
break;
default:
break;
}
break;
default:
c3 = getchar();
if (c3 == '~') {
fkey = c2;
fkeys[0] = 'f';
if (c2 == 63) {
strcpy(ps,"help");
goto done;
}
}
else if (getchar() != '~') { /* window was resized */
while(getchar() != '|');
printf("\2330 q"); /* get window bounds */
n = 0;
while((rep[n] = getchar()) != 'r' && n++ < 20);
width = (rep[n-3] - 48) * 10 + rep[n-2] - 48;
rep[n-1] = '\0';
set_var (LEVEL_SET, "_width", &rep[n-3]);
break;
}
else {
fkey = c3;
fkeys[0] = 'F';
}
sprintf(fkeys+1,"%d",fkey - 47);
if (!(s = get_var(LEVEL_SET, fkeys))) break;
tyahdptr = strcpy(typeahd,s);
break;
}
break;
case 8:
if (i > pl) {
i--;
printf("\010");
}
else break;
case 127:
if (i < max) {
int j,t,l = 0;
movmem(&line[i+1],&line[i],max-i);
--max;
printf("\233P");
j = width - i % width - 1; /* amount to end */
t = max/width - i/width; /* no of lines */
for(n = 0; n < t; n++) {
l += j; /* no. of char moved */
if (j) printf("\233%dC",j); /* goto eol */
printf("%c\233P",line[width*(i/width+n+1)-1]);
j = width-1;
}
if (t)
printf("\233%dD",l+t); /* get back */
}
break;
case 18:
n = i/width;
if (n) printf("\233%dF",n);
printf("\015\233J%s%s",prompt,ps);
i = max;
break;
case 27:
break;
case 1:
insert ^= 1;
break;
case 21:
case 24:
case 26:
if (i > pl)
printf("\233%dD",i-pl);
i = pl;
if (c1 == 26) break;
printf("\233J");
max = i;
line[i] = '\0';
break;
case 11: /* ^K */
printf("\233J");
max = i;
line[i] = '\0';
break;
case 28: /* ^\ */
SETCON;
return(NULL);
case 5:
printf("\233%dC",max - i);
i = max;
break;
case 10:
case 13:
line[max] = '\0';
done: printf("\233%dC\n",max - i);
SETCON;
strcpy(line, ps);
return(line);
default:
c1 &= 0x7f;
if (c1 == 9) c1 = 32;
if (c1 > 31 & i < 256) {
if (i < max && insert) {
int j,t,l = 0;
movmem(&line[i], &line[i+1], max - i);
printf("\233@%c",c1);
t = max/width - i/width;
j = width - i % width - 1;
for(n = 0; n < t; n++) {
l += j;
if (j) printf("\233%dC",j);
printf("\233@%c",line[width*(i/width+n+1)]);
j = width-1;
}
if (t) printf("\233%dD",l + t);
++max;
}
else {
if(i == pl && max == i) printf("\015%s%s",prompt,ps);
putchar(c1);
}
line[i++] = c1;
if (max < i) max = i;
line[max] = '\0';
}
}
}
SETCON;
return(NULL);
}
setrawcon(flag) /* -1L=RAW:, 0L=CON: */
long flag;
{
long packargs[8];
packargs[0]=flag;
SendPacket(994L, packargs, Myprocess->pr_ConsoleTask);
}
#endif
SHAR_EOF
cat << \SHAR_EOF > run.c
/*
* RUN.C
*
* (c)1986 Matthew Dillon 9 October 1986
*
* RUN handles running of external commands.
*
* Version 2.07M by Steve Drew 10-Sep-87
*
* Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
*
*/
extern char *v_path;
char *FindIt();
do_run(str)
char *str;
{
int i, len, retcode;
char buf[200]; /* enough space for 100 char cmd name + path stuff */
char *path;
char *p = av[0];
char **args = av+1;
while(*p++) *p &= 0x7F; /* allow "com mand" */
while(*args) { /* if any arg contains a space then */
if (index(*args,' ')) { /* surround with quotes, since must */
i = strlen(*args); /* of specified via "arg u ment" on */
movmem(*args,(*args)+1,i); /* original command line. */
args[0][0] = args[0][i+1] = '\"'; /* mpush in execom.c has */
args[0][i+2] = '\0'; /* allowed for these 2 extra bytes. */
}
++args;
}
if ((len = strlen(av[0])) > 100) { ierror(NULL,509); return -1; }
if (path = FindIt(av[0],"",buf)) retcode = myfexecv(path, av);
else {
Myprocess->pr_WindowPtr = (APTR)(-1);
/*
* manx's fexecv code only allows us 38
* chars for command name.
*/
if (len > 37) av[0][37] = '\0';
retcode = myfexecv(av[0], av);
Myprocess->pr_WindowPtr = NULL;
}
if (retcode < 0) {
char *copy;
if ((path = FindIt(av[0],".sh",buf)) == NULL) {
fprintf(stderr,"Command Not Found %s\n",av[0]);
return -1;
}
av[1] = buf; /* particular to do_source() */
copy = malloc(strlen(str)+3);
sprintf(copy,"x %s",str);
retcode = do_source(copy);
free(copy);
}
return retcode;
}
char *dofind(cmd, ext, buf)
char *cmd, *ext, *buf;
{
char *ptr, *s;
sprintf(buf,"%s%s",cmd,ext);
if (exists(buf)) return buf;
if (BaseName(buf)==buf) {
s = get_var(LEVEL_SET, v_path);
while (*s) {
for (ptr=buf; *s && *s!=','; ) *ptr++ = *s++;
sprintf(ptr, "%s%s", cmd, ext);
if (exists(buf)) return buf;
if (*s) s++;
}
}
return NULL;
}
char *FindIt(cmd,ext,buf)
char *cmd, *ext, *buf;
{
char *response;
Myprocess->pr_WindowPtr = (APTR)(-1);
response=dofind(cmd,ext,buf);
Myprocess->pr_WindowPtr = NULL;
return response;
}
myfexecv(cmd, argv)
char *cmd, **argv;
{
long ret_val;
struct FileHandle *fhp;
APTR sav_ret;
register char **ap, *cp, *arg;
int i;
long len, seg, sav, stksiz;
char buf[40];
union {
long *lp;
long ll;
} l, stk;
long oldcin, oldcout;
long doexec();
extern long _savsp;
if (seg = LoadPrg(cmd)) goto found;
l.lp = (long *) Mycli->cli_CommandDir;
while (l.ll) {
l.ll <<= 2;
sav = CurrentDir(l.lp[1]);
seg = LoadPrg(cmd);
CurrentDir(sav);
if (seg) goto found;
l.ll = *l.lp;
}
sprintf(buf, "c:%s", cmd);
if (seg = LoadPrg(buf)) goto found;
return -1;
found:
stksiz = 4 * Mycli->cli_DefaultStack;
if ((stk.lp = AllocMem(stksiz+8, 0L)) == 0) {
UnLoadPrg(seg);
return -1;
}
for (len=0,ap=argv+1;*ap;ap++)
len += strlen(*ap) + 1;
if (len==0) len++;
if ((cp = arg = AllocMem(len, 0L)) == 0) {
UnLoadPrg(seg);
FreeMem(stk.lp, stksiz+8);
return -1;
}
*stk.lp = stksiz + 8;
stk.ll += stksiz;
stk.lp[0] = stksiz;
stk.lp[1] = ((long *)_savsp)[2];
sav_ret = Myprocess->pr_ReturnAddr;
Myprocess->pr_ReturnAddr = (APTR) stk.lp;
sav = Mycli->cli_Module;
Mycli->cli_Module = seg;
for (ap=argv+1;*ap;ap++) {
strcpy(cp, *ap);
if (ap[1]) strcat(cp, " ");
cp += strlen(cp);
}
if (len==1) arg[1]='\0';
arg[len-1] = '\n';
cp = (char *)((long)Mycli->cli_CommandName << 2);
movmem(cp, buf, 40);
strcpy(cp+1, cmd);
cp[0] = strlen(cmd);
fhp = (struct FileHandle *) (Myprocess->pr_CIS << 2);
strncpy(fhp->fh_Buf<<2, arg, (int)(len < 200?len:199));
fhp->fh_Pos = 0;
fhp->fh_End = len < 200?len:199;
oldcin = Myprocess->pr_CIS;
oldcout = Myprocess->pr_COS;
ret_val = doexec(len, stksiz, stksiz+8, len, arg, (seg+1)<<2, stk.ll);
Myprocess->pr_CIS = oldcin;
Myprocess->pr_COS = oldcout;
fhp->fh_Pos = fhp->fh_End;
UnLoadPrg(Mycli->cli_Module);
Myprocess->pr_ReturnAddr = sav_ret;
Mycli->cli_Module = sav;
FreeMem(arg, len);
movmem(buf, cp, 40);
return ret_val;
}
static long doexec()
{
#asm
movem.l d3-d7/a2-a5,-(sp) ;save registers
lea savsp(pc),a0
move.l sp,(a0) ;save our sp
movem.l 8(a5),d0/d2/d3/d4/a0/a4/a7 ;load params
move.l 4(sp),a3 ;get old sp from CLI
movem.l 4(a3),a1/a2/a5/a6 ;get BCPL environment
move.l d0,12(a1) ;set length
move.l a0,d1 ;copy to dreg
lsr.l #2,d1 ;convert to BPTR
move.l d1,8(a1) ;set ptr
move.l a0,d1 ;copy to d1 as well
jsr (a4) ;call new program
movem.l (sp)+,d2/d3 ;get stk siz and old sp
move.l sp,a1 ;save current sp
move.l savsp(pc),sp ;get back our sp
movem.l (sp)+,d3-d7/a2-a5 ;get back registers
move.l d0,-(sp) ;save return code
sub.l d2,a1 ;back up a bit
sub.l #8,a1 ;back up over header
move.l (a1),d0 ;get size to free
move.l 4,a6 ;get ExecBase
jsr -210(a6) ;free the memory
move.l (sp)+,d0 ;get the return code
#endasm
}
#asm
savsp:
dc.l 0
#endasm
SHAR_EOF
cat << \SHAR_EOF > set.c
/*
* SET.C
*
* (c)1986 Matthew Dillon 9 October 1986
*
* Version 2.07M by Steve Drew 10-Sep-87
*
* Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
*
*/
extern char *v_titlebar, *v_verbose, *v_hist, *v_debug, *v_prompt;
extern struct Window *w;
#define MAXLEVELS (3 + MAXSRC)
struct MASTER {
struct MASTER *next;
struct MASTER *last;
char *name;
char *text;
};
static struct MASTER *Mbase[MAXLEVELS];
char *set_var(level, name, str)
register char *name, *str;
{
register struct MASTER *base = Mbase[level];
register struct MASTER *last;
register int len;
for (len = 0; isalphanum(name[len]); ++len);
while (base != NULL) {
if (strlen(base->name) == len && strncmp (name, base->name, len) == 0) {
Free (base->text);
goto gotit;
}
last = base;
base = base->next;
}
if (base == Mbase[level]) {
base = Mbase[level] = (struct MASTER *)malloc (sizeof(struct MASTER));
base->last = NULL;
} else {
base = (struct MASTER *)malloc (sizeof(struct MASTER));
base->last = last;
last->next = base;
}
base->name = malloc (len + 1);
bmov (name, base->name, len);
base->name[len] = 0;
base->next = NULL;
gotit:
base->text = malloc (strlen(str) + 1);
strcpy (base->text, str);
if (*name=='_') sys_vars();
return (base->text);
}
char *get_var (level, name)
register char *name;
{
register struct MASTER *base = Mbase[level];
register unsigned char *scr;
register int len;
for (scr = (unsigned char *)name; *scr && *scr != 0x80 && *scr != ' ' && *scr != ';' && *scr != '|'; ++scr);
len = scr - name;
while (base != NULL) {
if (strlen(base->name) == len && strncmp (name, base->name, len) == 0)
return (base->text);
base = base->next;
}
return (NULL);
}
unset_level(level)
{
register struct MASTER *base = Mbase[level];
while (base) {
Free (base->name);
Free (base->text);
Free (base);
base = base->next;
}
Mbase[level] = NULL;
}
unset_var(level, name)
char *name;
{
register struct MASTER *base = Mbase[level];
register struct MASTER *last = NULL;
register int len;
for (len = 0; isalphanum(name[len]); ++len);
while (base) {
if (strlen(base->name) == len && strncmp (name, base->name, len) == 0) {
if (base != Mbase[level])
last->next = base->next;
else
Mbase[level] = base->next;
if (base->next != NULL)
base->next->last = last;
if (base == Mbase[level])
Mbase[level] = base->next;
Free (base->name);
Free (base->text);
Free (base);
return (1);
}
last = base;
base = base->next;
}
return (-1);
}
do_unset_var(str, level)
char *str;
{
register unsigned int i;
for (i = 1; i < ac; ++i) unset_var (level, av[i]);
sys_vars();
return 0;
}
do_set_var(command, level)
char *command;
{
register struct MASTER *base = Mbase[level];
register char *str;
switch (ac) {
case 1:
while (base && !dobreak()) {
printf ("%-10s %s\n", base->name, base->text);
base = base->next;
}
break;
case 2:
if (str=get_var(level,av[1])) printf ("%-10s %s\n", av[1], str);
break;
default:
set_var (level, av[1], next_word (next_word (command)));
if (*av[1]=='_') sys_vars();
break;
}
return 0;
}
extern char trueprompt[100];
sys_vars()
{
register char *str, *t;
if (strcmp(w->Title, str=get_var(LEVEL_SET, v_titlebar)))
SetWindowTitles(w, str, -1L);
S_histlen=(str = get_var(LEVEL_SET, v_hist)) ? atoi(str) : 0;
debug =(get_var(LEVEL_SET, v_debug) !=NULL);
Verbose=(get_var(LEVEL_SET, v_verbose)!=NULL);
if (S_histlen < 2) S_histlen=2;
if ( (str=get_var(LEVEL_SET,v_prompt)) ==NULL) str="$ ";
t=trueprompt;
while (*str)
if (*str=='%' && Toupper(str[1])=='P') {
str+=2;
strcpy(t,get_var(LEVEL_SET,"_cwd"));
t+=strlen(t);
}
else *t++=*str++;
strcpy(t,"\2330m");
}
SHAR_EOF
cat << \SHAR_EOF > shell.h
/*
* SHELL.H
*
* (c)1986 Matthew Dillon 9 October 1986
*
*
* SHELL include file.. contains shell parameters and extern's
*
* Version 2.07M by Steve Drew 10-Sep-87
*
* Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
*
*/
#define RAW_CONSOLE 1 /* Set to 0 to compile out Cmd Line Editing */
#include <stdio.h>
#include <exec/exec.h>
#include <time.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include "shellfunctions.h"
#include <fcntl.h>
#include <libraries/arpbase.h>
#include <arpfunctions.h>
typedef struct FileInfoBlock FIB;
#define bmov movmem
#define MAXAV 256 /* Max. # arguments */
#define MAXSRC 5 /* Max. # of source file levels */
#define MAXIF 10 /* Max. # of if levels */
#define MAXALIAS 20 /* Max. # of alias levels */
#define MAXMYFILES 9 /* Max. # of internal files */
#define LEVEL_SET 0 /* which variable list to use */
#define LEVEL_ALIAS 1
#define LEVEL_LABEL 2
/* EXECOM.C defines */
#define FL_DOLLAR 0x01 /* One of the following */
#define FL_BANG 0x02
#define FL_PERCENT 0x04
#define FL_QUOTE 0x08
#define FL_IDOLLAR 0x10 /* Any or all of the following may be set */
#define FL_EOC 0x20
#define FL_EOL 0x40
#define FL_OVERIDE 0x80
#define FL_WILD 0x100
#define FL_MASK (FL_DOLLAR|FL_BANG|FL_PERCENT|FL_QUOTE)
#ifndef NULL
#define NULL 0L
#endif
#define CHECKBREAK() dobreak()
#ifndef AZTEC_C
struct _dev {
long fd;
short mode;
};
#endif
struct HIST {
struct HIST *next, *prev; /* doubly linked list */
char *line; /* line in history */
};
struct PERROR {
int errnum; /* Format of global error lookup */
char *errstr;
};
struct DPTR { /* Format of directory fetch pointer */
BPTR lock; /* lock on directory */
FIB *fib; /* mod'd fib for entry */
};
extern struct HIST *H_head, *H_tail;
extern struct PERROR Perror[];
extern struct DPTR *dopen();
extern char *set_var(), *get_var(), *next_word();
extern char *get_history(), *compile_av(), *get_pwd();
extern char *malloc(), *strcpy(), *strcat(), *index();
extern char **expand();
extern char *av[];
extern char *Current;
extern int H_len, H_tail_base, H_stack;
extern int E_stack;
extern int Src_stack, If_stack, forward_goto;
extern int ac;
extern int debug, Rval, Verbose, disable, Quit;
extern int Lastresult;
extern int Exec_abortline;
extern int S_histlen;
extern unsigned int options;
extern long Cin, Cout, Cout_append;
extern char *Cin_name, *Cout_name;
extern char Cin_type, Cout_type; /* these variables are in transition */
extern char *Pipe1, *Pipe2;
extern long Errno;
extern long Src_base[MAXSRC];
extern long Src_pos[MAXSRC];
extern char If_base[MAXIF];
extern struct Process *Myprocess;
extern struct CommandLineInterface *Mycli;
extern long atol(), Atol(), myatol();
SHAR_EOF
cat << \SHAR_EOF > shellfunctions.h
typedef long cList;
extern int Enable_Abort;
long AbleICR();
long AbortIO();
long ActivateGadget();
void ActivateWindow();
void AddAnimOb();
void AddBob();
void AddConfigDev();
void AddDevice();
long AddDosNode();
void AddFont();
void AddFreeList();
short AddGadget();
unsigned short AddGList();
void AddHead();
struct Interrupt * AddICRVector();
void AddIntServer();
void AddLibrary();
long AddMemList();
void AddPort();
void AddResource();
void AddSemaphore();
void AddTail();
void AddTask();
void AddTime();
void AddVSprite();
long Alert();
void * AllocAbs();
long AllocBoardMem();
cList AllocCList();
struct ConfigDev * AllocConfigDev();
struct MemList * AllocEntry();
unsigned long AllocExpansionMem();
void * AllocMem();
long AllocPotBits();
void * AllocRaster();
char * AllocRemember();
long AllocSignal();
long AllocTrap();
struct WBObject * AllocWBObject();
void * Allocate();
void AlohaWorkbench();
void AndRectRegion();
long AndRegionRegion();
void Animate();
short AreaDraw();
long AreaEllipse();
void AreaEnd();
short AreaMove();
void AskFont();
long AskSoftStyle();
long AttemptLockLayerRom();
long AttemptSemaphore();
short AutoRequest();
long AvailFonts();
long AvailMem();
void BeginIO();
void BeginRefresh();
void BeginUpdate();
void BeginLayer();
long BltBitMap();
long BltBitMapRastPort();
void BltClear();
void BltMaskBitMapRastPort();
void BltPattern();
void BltTemplate();
struct Window * BuildSysRequest();
char * BumpRevision();
void Cause();
void CBump();
struct Events * CDInputHandler();
void ChangeSprite();
struct IORequest * CheckIO();
short ClearDMRequest();
void ClearEOL();
void ClearMenuStrip();
void ClearPointer();
void ClearRegion();
long ClearRectRegion();
void ClearScreen();
void ClipBit();
void Close();
void CloseDevice();
void CloseFont();
void CloseLibrary();
void CloseScreen();
void CloseWindow();
short CloseWorkBench();
void CMove();
short CmpTime();
long ConcatCList();
long ConfigBoard();
long ConfigChain();
long ConsoleDevice();
long CopperListInit();
cList CopyCList();
void CopyMem();
void CopyMemQuick();
void CopySBitMap();
struct Layer * CreateBehindLayer();
BPTR CreateDir();
struct MsgPort * CreatePort();
struct Process * CreateProc();
struct IOStdReq * CreateStdIO();
struct Task * CreateTask();
struct Layer * CreateUpfrontLayer();
BPTR CurrentDir();
void CurrentTime();
void CWait();
long * DateStamp();
void Deallocate();
void Debug();
void Delay();
short DeleteFile();
void DeleteLayer();
void DeletePort();
void DeleteStdIO();
void DeleteTask();
struct Process * DeviceProc();
void Disable();
void DisownBlitter();
short DisplayAlert();
void DisplayBeep();
void DisposeRegion();
void DoCollision();
long DoIO();
short DoubleClick();
void Draw();
void DrawBorder();
void DrawEllipse();
void DrawGList();
void DrawImage();
BPTR DupLock();
void Enable();
void EndRefresh();
void EndRequest();
void EndUpdate();
void Enqueue();
short ExNext();
short Examine();
short Execute();
void Exit();
struct ConfigDev * FindConfigDev();
struct Node * FindName();
struct MsgPort * FindPort();
struct Resident * FindResident();
struct SignalSemaphore * FindSemaphore();
struct Task * FindTask();
char * FindToolType();
short Flood();
void FlushCList();
void Forbid();
void FreeBoardMem();
void FreeCList();
void FreeColorMap();
void FreeConfigDev();
void FreeCopList();
void FreeCprList();
void FreeDiskObject();
void FreeEntry();
void FreeExpansionMem();
void FreeFreeList();
void FreeGBuffers();
void FreeMem();
void FreePotBits();
void FreeRaster();
void FreeRemember();
void FreeSignal();
void FreeSprite();
void FreeSysRequest();
void FreeTrap();
void FreeVPortCopLists();
void FreeWBObject();
long GetCC();
long GetCLBuf();
short GetCLChar();
short GetCLWord();
struct ColorMap * GetColorMap();
long GetCurrentBinding();
struct Preferences * GetDefPrefs();
struct DiskObject * GetDiskObject();
short GetGBuffers();
long GetIcon();
struct Message * GetMsg();
struct Preferences * GetPrefs();
short GetRGB4();
long GetScreenData();
short GetSprite();
struct WBObject * GetWBObject();
long IncrCLMark();
short Info();
void InitArea();
void InitBitMap();
long InitCLPool();
void InitCode();
void InitGMasks();
void InitGels();
void InitMasks();
void InitRastPort();
void InitRequester();
void InitResident();
void InitSemaphore();
void InitStruct();
void InitTmpRas();
void InitVPort();
void InitView();
BPTR Input();
void Insert();
struct Region * InstallClipRegion();
long IntuiTextLength();
struct InputEvent * Intuition();
long IoErr();
short IsInteractive();
struct MenuItem * ItemAddress();
void LoadRGB4();
struct Segment * LoadSeg();
void LoadView();
BPTR Lock();
void LockLayer();
void LockLayerInfo();
void LockLayerRom();
void LockLayers();
struct DeviceNode * MakeDosNode();
long MakeFunctions();
struct Library * MakeLibrary();
void MakeScreen();
void MakeVPort();
long MarkCList();
long MatchToolValue();
void ModifyIDCMP();
void ModifyProp();
void Move();
long MoveLayer();
void MoveScreen();
void MoveSprite();
void MoveWindow();
void MrgCop();
void NewList();
void NewModifyProp();
struct Region * NewRegion();
void ObtainConfigBinding();
void ObtainSemaphore();
void ObtainSemaphoreList();
void OffGadget();
void OffMenu();
void OnGadget();
void OnMenu();
BPTR Open();
long OpenDevice();
struct Font * OpenDiskFont();
struct Font * OpenFont();
void OpenIntuition();
struct Library * OpenLibrary();
struct MiscResource * OpenResource();
struct Screen * OpenScreen();
struct Window * OpenWindow();
short OpenWorkBench();
void OrRectRegion();
long OrRegionRegion();
BPTR Output();
void OwnBlitter();
BPTR ParentDir();
short PeekCLMark();
void Permit();
void PolyDraw();
void PrintIText();
long PutCLBuf();
long PutCLChar();
long PutCLWord();
short PutDiskObject();
long PutIcon();
void PutMsg();
long PutWBObject();
void QBSBlit();
void QBlit();
short RawKeyConvert();
long Read();
char ReadExpansionByte();
long ReadExpansionRom();
short ReadPixel();
void RectFill();
void RefreshGadgets();
void RefreshGList();
void RefreshWindowFrame();
void ReleaseConfigBinding();
void ReleaseSemaphore();
void ReleaseSemaphoreList();
void RemConfigDev();
long RemDevice();
void RemFont();
struct Node * RemHead();
void RemIBob();
void RemICRVector();
void RemIntServer();
long RemLibrary();
unsigned short RemoveGList();
void RemPort();
void RemResource();
void RemSemaphore();
struct Node * RemTail();
void RemTask();
void RemVSprite();
void RemakeDisplay();
void Remove();
unsigned short RemoveGadget();
short Rename();
void ReplyMsg();
void ReportMouse();
short Request();
void RethinkDisplay();
void ScreenToBack();
void ScreenToFront();
void ScrollLayer();
void ScrollRaster();
void ScrollVPort();
long Seek();
void SendIO();
void SetAPen();
void SetBPen();
void SetCollision();
short SetComment();
void SetCurrentBinding();
short SetDMRequest();
void SetDRMd();
long SetExcept();
long SetFont();
long SetFunction();
long SetICR();
struct Interrupt * SetIntVector();
short SetMenuStrip();
void SetPointer();
struct Preferences * SetPrefs();
short SetProtection();
void SetRast();
void SetRGB4();
void SetRGB4CM();
long SetSR();
long SetSignal();
long SetSoftStyle();
short SetTaskPri();
void SetWindowTitles();
void ShowTitle();
void Signal();
long SizeCList();
short SizeLayer();
void SizeWindow();
void SortGList();
cList SplitCList();
cList SubCList();
void SubTime();
void SubLibrary();
void SumKickData();
long SuperState();
void SwapBitsRastPortClipRect();
void SyncSBitMap();
long Text();
long TextLength();
long Translate();
long UnGetCLChar();
long UnGetCLWord();
void UnLoadSeg();
void UnLock();
short UnPutCLChar();
short UnPutCLWord();
void UnlockLayer();
void UnlockLayerInfo();
void UnlockLayerRom();
void UnlockLayers();
short UpfrontLayer();
void UserState();
short VBeamPos();
struct View * ViewAddress();
struct ViewPort * ViewPortAddress();
short WBenchToBack();
short WBenchToFront();
long Wait();
void WaitBOVP();
void WaitBlit();
short WaitForChar();
long WaitIO();
struct Message * WaitPort();
void WaitTOF();
struct Layer * WhichLayer();
short WindowLimits();
void WindowToBack();
void WindowToFront();
long Write();
long WriteExpansionByte();
void WritePixel();
void WritePotgo();
void XorRectRegion();
long XorRegionRegion();
SHAR_EOF
cat << \SHAR_EOF > sub.c
/*
* SUB.C
*
* (c)1986 Matthew Dillon 9 October 1986
*
* Version 2.07M by Steve Drew 10-Sep-87
*
* Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
*
*/
extern char *v_lasterr, *v_stat;
#define HM_STR 0 /* various HISTORY retrieval modes */
#define HM_REL 1
#define HM_ABS 2
/* extern BPTR Clock; */
seterr()
{
char buf[32];
int stat;
sprintf(buf, "%d", Lastresult);
set_var(LEVEL_SET, v_lasterr, buf);
stat = atoi(get_var(LEVEL_SET, v_stat));
if (stat < Lastresult) stat = Lastresult;
sprintf(buf, "%d", stat);
set_var(LEVEL_SET, v_stat, buf);
}
char *
next_word(str)
register char *str;
{
while (*str && *str != ' ' && *str != 9 && (unsigned char)*str != 0xA0)
++str;
while (*str && (*str == ' ' || *str == 9 || (unsigned char)*str == 0xA0))
++str;
return (str);
}
char *
compile_av(av, start, end, delim)
char **av;
unsigned char delim;
{
char *cstr;
int len;
register unsigned int i;
len = 0;
for (i = start; i < end; ++i) len += strlen(av[i]) + 1;
cstr = malloc(len + 1);
*cstr = '\0';
for (i = start; i < end; ++i) {
if (debug) fprintf (stderr, "AV[%2d] :%s:\n", i, av[i]);
strcat (cstr, av[i]);
if (i + 1 < end) strncat(cstr, &delim, 1);
}
return (cstr);
}
/*
* FREE(ptr) --frees without actually freeing, so the data is still good
* immediately after the free.
*/
Free(ptr)
char *ptr;
{
static char *old_ptr;
if (old_ptr)
free (old_ptr);
old_ptr = ptr;
}
/*
* Add new string to history (H_head, H_tail, H_len,
* S_histlen
*/
add_history(str)
char *str;
{
register struct HIST *hist;
if (H_head != NULL && strcmp(H_head->line, str) == 0)
return(0);
while (H_len > S_histlen)
del_history();
hist = (struct HIST *)malloc (sizeof(struct HIST));
if (H_head == NULL) {
H_head = H_tail = hist;
hist->next = NULL;
} else {
hist->next = H_head;
H_head->prev = hist;
H_head = hist;
}
hist->prev = NULL;
hist->line = malloc (strlen(str) + 1);
strcpy (hist->line, str);
++H_len;
}
del_history()
{
if (H_tail) {
--H_len;
++H_tail_base;
free (H_tail->line);
if (H_tail->prev) {
H_tail = H_tail->prev;
free (H_tail->next);
H_tail->next = NULL;
} else {
free (H_tail);
H_tail = H_head = NULL;
}
}
}
char *
get_history(ptr)
char *ptr;
{
register struct HIST *hist;
register int len;
int mode = HM_REL;
int num = 1;
char *str;
char *result = NULL;
if (ptr[1] >= '0' && ptr[1] <= '9') {
mode = HM_ABS;
num = atoi(&ptr[1]);
goto skip;
}
switch (ptr[1]) {
case '!':
break;
case '-':
num += atoi(&ptr[2]);
break;
default:
mode = HM_STR;
str = ptr + 1;
break;
}
skip:
switch (mode) {
case HM_STR:
len = strlen(str);
for (hist = H_head; hist; hist = hist->next) {
if (strncmp(hist->line, str, len) == 0 && *hist->line != '!') {
result = hist->line;
break;
}
}
break;
case HM_REL:
for (hist = H_head; hist && num--; hist = hist->next);
if (hist)
result = hist->line;
break;
case HM_ABS:
len = H_tail_base;
for (hist = H_tail; hist && len != num; hist = hist->prev, ++len);
if (hist)
result = hist->line;
break;
}
if (result) {
fprintf(stderr,"%s\n",result);
return(result);
}
printf("History failed\n");
return ("");
}
replace_head(str)
char *str;
{
if (str == NULL)
str = "";
if (H_head) {
free (H_head->line);
H_head->line = malloc (strlen(str)+1);
strcpy (H_head->line, str);
}
}
pError(str)
char *str;
{
int ierr = (long)IoErr();
ierror(str, ierr);
}
ierror(str, err)
register char *str;
{
register struct PERROR *per = Perror;
if (err) {
for (; per->errstr; ++per) {
if (per->errnum == err) {
fprintf (stderr, "%s%s%s\n",
per->errstr,
(str) ? ": " : "",
(str) ? str : "");
return ((short)err);
}
}
fprintf (stderr, "Unknown DOS error %d %s\n", err, (str) ? str : "");
}
return ((short)err);
}
/*
* Disk directory routines
*
* dptr = dopen(name, stat)
* struct DPTR *dptr;
* char *name;
* int *stat;
*
* dnext(dptr, name, stat)
* struct DPTR *dptr;
* char **name;
* int *stat;
*
* dclose(dptr) -may be called with NULL without harm
*
* dopen() returns a struct DPTR, or NULL if the given file does not
* exist. stat will be set to 1 if the file is a directory. If the
* name is "", then the current directory is openned.
*
* dnext() returns 1 until there are no more entries. The **name and
* *stat are set. *stat = 1 if the file is a directory.
*
* dclose() closes a directory channel.
*
*/
struct DPTR *
dopen(name, stat)
char *name;
int *stat;
{
struct DPTR *dp;
*stat = 0;
dp = (struct DPTR *)malloc(sizeof(struct DPTR));
if (*name == '\0')
dp->lock = DupLock(Myprocess->pr_CurrentDir);
else
dp->lock = Lock (name,ACCESS_READ);
if (dp->lock == NULL) {
free (dp);
return (NULL);
}
dp->fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
if (!Examine (dp->lock, dp->fib)) {
pError (name);
dclose (dp);
return (NULL);
}
if (dp->fib->fib_DirEntryType >= 0)
*stat = 1;
return (dp);
}
dnext(dp, pname, stat)
struct DPTR *dp;
char **pname;
int *stat;
{
if (dp == NULL)
return (0);
if (ExNext (dp->lock, dp->fib)) {
*stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
*pname = dp->fib->fib_FileName;
return (1);
}
return (0);
}
dclose(dp)
struct DPTR *dp;
{
if (dp == NULL)
return (1);
if (dp->fib)
FreeMem (dp->fib,(long)sizeof(*dp->fib));
if (dp->lock)
UnLock (dp->lock);
free (dp);
return (1);
}
isdir(file)
char *file;
{
register struct DPTR *dp;
int stat;
stat = 0;
if (dp = dopen (file, &stat))
dclose(dp);
return (stat == 1);
}
free_expand(av)
register char **av;
{
char **base = av;
if (av) {
while (*av) {
free (*av);
++av;
}
free (base);
}
}
/*
* EXPAND(base,pac)
* base - char * (example: "df0:*.c")
* pac - int * will be set to # of arguments.
*
* 22-May-87 SJD. Heavily modified to allow recursive wild carding and
* simple directory/file lookups. Returns a pointer to
* an array of pointers that contains the full file spec
* eg. 'df0:c/sear*' would result in : 'df0:C/Search'
*
* Now no longer necessary to Examine the files a second time
* in do_dir since expand will return the full file info
* appended to the file name. Set by formatfile().
* eg. fullfilename'\0'rwed NNNNNN NNNN DD-MMM-YY HH:MM:SS
*
* Caller must call free_expand when done with the array.
*
* base bname = ename =
* ------ ------- -------
* "*" "" "*"
* "!*.info" "" "*.info" (wild_exclude set)
* "su*d/*" "" "*" (tail set)
* "file.*" "" "file.*"
* "df0:c/*" "df0:c" "*"
* "" "" "*"
* "df0:.../*" "df0:" "*" (recur set)
* "df0:sub/.../*" "df0:sub" "*" (recur set)
*
* ---the above base would be provided by execom.c or do_dir().
* ---the below base would only be called from do_dir().
*
* "file.c" "file.c" "" if (dp == 0) fail else get file.c
* "df0:" "df0:" "*"
* "file/file" "file/file" "" (dp == 0) so fail
* "df0:.../" "df0:" "*" (recur set)
*
*/
char **
expand(base, pac)
char *base;
int *pac;
{
register char *ptr;
char **eav = (char **)malloc(sizeof(char *) * (2));
short eleft, eac;
char *name;
char *svfile();
char *bname, *ename, *tail;
int stat, recur, scr, bl;
register struct DPTR *dp;
*pac = recur = eleft = eac = 0;
base = strcpy(malloc(strlen(base)+1), base);
for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
if (!*ptr) /* no wild cards */
--ptr;
else
for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
if (ptr < base) {
bname = strcpy (malloc(1), "");
} else {
scr = ptr[1];
ptr[1] = '\0';
if (!strcmp(ptr-3,".../")) {
recur = 1;
*(ptr-3) = '\0';
}
bname = strcpy (malloc(strlen(base)+2), base);
ptr[1] = scr;
}
bl = strlen(bname);
ename = ++ptr;
for (; *ptr && *ptr != '/'; ++ptr);
scr = *ptr;
*ptr = '\0';
if (scr) ++ptr;
tail = ptr;
if ((dp = dopen (bname, &stat)) == NULL || (stat == 0 && *ename)) {
free (bname);
free (base);
free (eav);
return (NULL);
}
if (!stat) { /* eg. 'dir file' */
char *p,*s;
for(s = p = bname; *p; ++p) if (*p == '/' || *p == ':') s = p;
if (s != bname) ++s;
*s ='\0';
eav[eac++] = svfile(bname,dp->fib->fib_FileName,dp->fib);
goto done;
}
if (!*ename) ename = "*"; /* eg. dir df0: */
if (*bname && bname[bl-1] != ':' && bname[bl-1] != '/') { /* dir df0:c */
bname[bl] = '/';
bname[++bl] = '\0';
}
while ((dnext (dp, &name, &stat)) && !breakcheck()) {
int match = compare_ok(ename,name);
if (match && !(!recur && *tail)) {
if (eleft < 2) {
char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
movmem (eav, scrav, (eac + 1) << 2);
free (eav);
eav = scrav;
eleft = 10;
}
eav[eac++] = svfile(bname,name,dp->fib);
--eleft;
}
if ((*tail && match) || recur) {
int alt_ac;
char *search, **alt_av, **scrav;
BPTR lock;
if (!stat) /* expect more dirs, but this not a dir */
continue;
lock = CurrentDir (dp->lock);
search = malloc(strlen(ename)+strlen(name)+strlen(tail)+5);
strcpy (search, name);
strcat (search, "/");
if (recur) {
strcat(search, ".../");
strcat(search, ename);
}
strcat (search, tail);
scrav = alt_av = expand (search, &alt_ac);
/* free(search); */
CurrentDir (lock);
if (scrav) {
while (*scrav) {
int l;
if (eleft < 2) {
char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
movmem (eav, scrav, (eac + 1) << 2);
free (eav);
eav = scrav;
eleft = 10;
}
l = strlen(*scrav);
scrav[0][l] = ' ';
eav[eac] = malloc(bl+l+45);
strcpy(eav[eac], bname);
strcat(eav[eac], *scrav);
eav[eac][l+bl] = '\0';
free (*scrav);
++scrav;
--eleft, ++eac;
}
free (alt_av);
}
}
}
done:
dclose (dp);
*pac = eac;
eav[eac] = NULL;
free (bname);
free (base);
if (eac) {
return (eav);
}
free (eav);
return (NULL);
}
/*
* Compare a wild card name with a normal name
*/
#define MAXB 8
compare_ok(wild, name)
char *wild, *name;
{
register char *w = wild;
register char *n = name;
char *back0[MAXB], *back1[MAXB];
int bi=0, queryflag;
if (*w=='!') return !compare_ok(wild+1,name);
if (queryflag=(*w=='&')) w++;
while (*n || *w) {
switch (*w) {
case '*':
if (bi==MAXB) { printf(stderr,"Too many levels of '*'\n"); return 0; }
back0[bi] = w;
back1[bi] = n;
++bi;
++w;
continue;
goback:
--bi;
while (bi >= 0 && *back1[bi] == '\0') --bi;
if (bi < 0) return 0;
w = back0[bi] + 1;
n = ++back1[bi];
++bi;
continue;
case '?':
if (!*n) goto goback;
break;
default:
if (Toupper(*n)!=Toupper(*w)) goto goback;
break;
}
if (*n) ++n;
if (*w) ++w;
}
if (queryflag) {
char in[256];
printf("Select \23337m%-16s\2330m [y/n] ? ",name);
gets(in);
return (Toupper(*in)=='Y');
}
return 1;
}
char *svfile(s1,s2,fib)
char *s1,*s2;
FIB *fib;
{
char *p = malloc (strlen(s1)+strlen(s2)+45);
strcpy(p, s1);
strcat(p, s2);
formatfile(p,fib);
return p;
}
/* will have either of these formats:
*
* fullfilename'\0'hsparwed <Dir> DD-MMM-YY HH:MM:SS\n'\0'
* fullfilename'\0'hsparwed NNNNNN NNNN DD-MMM-YY HH:MM:SS\n'\0'
* 1111111111222222222233333333334 4 4
* 01234567890123456789012345678901234567890 1 2
*/
formatfile(str,fib)
char *str;
FIB *fib;
{
char *dates();
int i;
while(*str++);
for (i=7; i>=0; i--)
*str++ = ((fib->fib_Protection & (1L<<i)) ? "hspa----" : "----rwed")[7-i];
if (fib->fib_DirEntryType < 0)
sprintf(str," %6ld %4ld ", (long)fib->fib_Size, (long)fib->fib_NumBlocks);
else strcpy(str," <Dir> ");
strcat(str,dates(&fib->fib_Date));
}
/* Sort routines */
long cmp(s1, s2)
char **s1, **s2;
{
return (long)Strcmp(*s1, *s2);
}
Cmp() {
#asm
public _geta4
movem.l d2-d3/a4/a6,-(sp)
movem.l a0/a1,-(sp)
bsr _geta4
bsr _cmp
addq.l #8,sp
movem.l (sp)+,d2-d3/a4/a6
#endasm
}
QuickSort(av, n)
char *av[];
int n;
{
QSort(av, (long)n, 4L, Cmp);
}
SHAR_EOF
# End of shell archive
exit 0
--
Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page
Have five nice days.